// "Copyright [2021] <Copyright Shengkai Lin>"

#include "optical_transceiver.h"
#include "inet/common/packet/Message.h"
#include "inet/linklayer/ethernet/EthernetCommand_m.h"

namespace ai_sim {

Define_Module(OpticalTransceiver);

void OpticalTransceiver::initialize() {
    my_index = par("my_index");
    my_global_index = par("my_global_index");
    is_active = true;
}

void OpticalTransceiver::handleMessage(omnetpp::cMessage *msg) {
    omnetpp::cGate* inPort = msg->getArrivalGate();
    if (inPort == gate("out_port$i")) {
        if (is_active) {
            send(msg, "nic_port$o");
        } else {
            //std::cout << "Packet drop at optical transceiver" << endl;
        }
    } else if (inPort == gate("nic_port$i")) {
        if (is_active) {
            send(msg, "out_port$o");
        } else {
            //std::cout << "Packet drop at optical transceiver" << endl;
        }
    } else {
        // TODO
        delete msg;
    }
}

void OpticalTransceiver::NotifyPortTempDown() {
    if (!is_active) {
        return;
    }
    auto* request = new inet::Request("NotifyPortTempDown", inet::EthernetStatusInd::ETHERNET_I_PORT_STATUS);
    auto* ctrl = new inet::EthernetPortTempDownIndication();
    request->setControlInfo(ctrl);
    send(request, "nic_port$o");
    is_active = false;
}

void OpticalTransceiver::NotifyPortUp() {
    if (is_active) {
        return;
    }
    auto* request = new inet::Request("NotifyPortUp", inet::EthernetStatusInd::ETHERNET_I_PORT_STATUS);
    auto* ctrl = new inet::EthernetPortUpIndication();
    request->setControlInfo(ctrl);
    send(request, "nic_port$o");
    is_active = true;
}

}  // namespace ai_sim
